// 接口合并
interface Box {
  height: number
  width: number
}

interface Box {
  length: number
}

// 这样的设计主要是为了兼容 JavaScript 的行为。
// JavaScript 开发者常常对全局对象或者外部库，添加自己的属性和方法

interface Document {
  foo: string
}

document.foo = 'Hello'

// 名接口合并时，同一个属性如果有多个类型声明，彼此不能有类型冲突
interface A1 {
  id: string
}

interface A1 {
  // id: number 报错
}

// 如果两个 interface 组成的联合类型存在同名属性，那么该属性的类型也是联合类型
interface Circle {
  area: bigint
}

interface Rectangle {
  area: number
}

// declare命令表示变量s的具体定义，由其他脚本文件给出
declare const s: Circle | Rectangle

s.area // number | bigint

// interface 与 type 的异同点
/**
 * 1. 都能为对象类型起别名 但是 type 还能定义其他基础类型
 * 2. interface 支持继承 但是 type 不支持
 * 3. interface 重复声明 会自动合并  但是 type 不支持重复声明
 * 4. interface 不包含属性映射 但是 type 支持
 * 5. this 关键字只能用于 interface 
 * 6. type 可以扩展原始数据类型，interface 不行
 * 7. interface 无法表达某些复杂类型（比如交叉类型和联合类型）
 * 综上所述，如果有复杂的类型运算，那么没有其他选择只能使用 type
 * 一般情况下，interface灵活性比较高，便于扩充类型或自动合并，建议优先使用
 */